<template>
  <div ref="container" style="width: 100%; height: 100vh;">
    <div v-if="loading" class="loading-overlay">加载中... {{ loadProgress }}%</div>
    <div v-if="error" class="error-overlay">{{ errorMessage }}</div>
  </div>
</template>

<script>
import * as THREE from 'three';
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

export default {
  name: 'ThreeCom',
  data() {
    return {
      scene: null,
      camera: null,
      renderer: null,
      controls: null,
      loader: new FBXLoader(),
      loadProgress: 0,
      loading: false,
      error: false,
      errorMessage: '',

      // 新增鼠标交互相关数据
      raycaster: new THREE.Raycaster(),
      mouse: new THREE.Vector2(),
      hoveredObject: null,
      originalMaterials: new Map(),
      highlightMaterial: new THREE.MeshBasicMaterial({
        color: 0xcccccc,
        transparent: true,
        opacity: 0.5
      })
      // 高亮为表面发光

    };
  },

  mounted() {
    this.initScene();
    this.loadModel();
    window.addEventListener('resize', this.handleResize);
  },

  beforeDestroy() {
    this.cleanup();
  },

  methods: {
    // 初始化场景
    initScene() {
      // 基础场景设置
      this.scene = new THREE.Scene();
      // this.scene.background = new THREE.Color(0x000000);

      // 渲染器配置
      this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true , preserveDrawingBuffer: true});
      this.renderer.setSize(window.innerWidth, window.innerHeight);
      // this.renderer.shadowMap.enabled = true;
      this.renderer.setClearColor(0xcccccc);
      this.$refs.container.appendChild(this.renderer.domElement);

      // 相机配置
      this.camera = new THREE.PerspectiveCamera(
        100,
        window.innerWidth / window.innerHeight,
        0.1,
        1000
      );
      // 初始相机位置
      this.camera.position.set(0, 50, 100);
      this.camera.lookAt(0, 0, 0);
      // 控制器
      this.controls = new OrbitControls(this.camera, this.renderer.domElement);
      this.controls.enableDamping = true;

      // 添加鼠标事件监听
      // this.renderer.domElement.addEventListener('mousemove', this.handleMouseMove);

      // 添加环境光
      const ambientLight = new THREE.AmbientLight(0xffffff, 0.8);
      this.scene.add(ambientLight);

      // 添加平行光
      const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
      directionalLight.position.set(10, 20, 15);
      this.scene.add(directionalLight);

      // 辅助工具
      const axesHelper = new THREE.AxesHelper(1000);
      this.scene.add(axesHelper);

      // 显示网格
      const gridHelper = new THREE.GridHelper(1000, 100);
      this.scene.add(gridHelper);

    },

    // 加载模型
    async loadModel() {
      this.loading = true;
      try {
        const model = await new Promise((resolve, reject) => {
          this.loader.load(
            '/宁海模型/场景模型.fbx',
            model => {
              this.prepareModel(model);
              resolve(model);
            },
            progress => {
              this.loadProgress = Math.round((progress.loaded / progress.total) * 100);
            },
            error => reject(error)
          );
        });

        this.scene.add(model);
        // this.setCameraPosition(model);
        this.animate();
      } catch (error) {
        this.handleError(error);
      } finally {
        this.loading = false;
      }
    },

    // 模型预处理
    prepareModel(model) {

      // 居中处理
      // const box = new THREE.Box3().setFromObject(model);
      // const center = box.getCenter(new THREE.Vector3());
      // model.position.sub(center);

      // 缓存原始材质并启用阴影
      model.traverse(child => {
        if (child.isMesh) {
          child.castShadow = true;
          child.receiveShadow = true;
          this.originalMaterials.set(child.uuid, child.material);
        }
      });
    },

    // 设置相机位置
    setCameraPosition(model) {
      const box = new THREE.Box3().setFromObject(model);
      const size = box.getSize(new THREE.Vector3());
      const center = box.getCenter(new THREE.Vector3());

      this.camera.position.copy(center).add(
        new THREE.Vector3(size.x * 1.5, size.y * 2, size.z * 1.5)
      );
      this.controls.target.copy(center);
    },

    // 鼠标移动处理
    handleMouseMove(event) {
      // 计算标准化鼠标坐标
      const rect = this.renderer.domElement.getBoundingClientRect();
      this.mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
      this.mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;

      this.checkIntersections();
    },

    // 射线检测
    checkIntersections() {
      this.raycaster.setFromCamera(this.mouse, this.camera);

      // 检测所有可交互对象
      const intersects = this.raycaster.intersectObjects(
        this.scene.children,
        true // 递归检测子对象
      );

      console.log(intersects);

      // 清除旧高亮
      if (this.hoveredObject) {
        this.restoreMaterial(this.hoveredObject);
        this.hoveredObject = null;
      }

      // 处理新交点
      if (intersects.length > 0) {
        const intersectedObject = intersects[0].object;
        if (this.originalMaterials.has(intersectedObject.uuid)) {
          this.hoveredObject = intersectedObject;
          this.applyHighlight(intersectedObject);
        }
      }
    },

    // 应用高亮材质
    applyHighlight(object) {
      object.material = this.highlightMaterial;
    },

    // 恢复原始材质
    restoreMaterial(object) {
      object.material = this.originalMaterials.get(object.uuid);
    },

    // 窗口调整
    handleResize() {
      this.camera.aspect = window.innerWidth / window.innerHeight;
      this.camera.updateProjectionMatrix();
      this.renderer.setSize(window.innerWidth, window.innerHeight);
    },

    // 错误处理
    handleError(error) {
      console.error(error);
      this.error = true;
      this.errorMessage = error.message.includes('404')
        ? '模型文件未找到'
        : `加载错误: ${error.message}`;
    },

    // 场景清理
    cleanup() {
      window.removeEventListener('resize', this.handleResize);
      this.renderer.domElement.removeEventListener('mousemove', this.handleMouseMove);
      this.controls.dispose();
      this.renderer.dispose();
    },

    // 动画循环
    animate() {
      requestAnimationFrame(this.animate);
      this.controls.update();
      this.renderer.render(this.scene, this.camera);
    }
  },


};
</script>
<style>
.loading-overlay, .error-overlay {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  padding: 12px 24px;
  border-radius: 8px;
  font-family: Arial;
  font-size: 14px;
  color: white;
  z-index: 1000;
  box-shadow: 0 2px 6px rgba(0,0,0,0.2);
}
.loading-overlay {
  background: #2196F3;
}
.error-overlay {
  background: #f44336;
}
</style>